package com.mdd.common.util;

import com.beust.jcommander.internal.Lists;
import com.github.benmanes.caffeine.cache.Cache;
import com.mdd.common.config.GlobalConfig;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Map;

@Component
@RequiredArgsConstructor
public class CaffeineUtils {

    private static final String redisPrefix = GlobalConfig.redisPrefix;
    private static Cache<String, Object> CACHE;

    private final Cache<String, Object> cache;

    @PostConstruct
    private void init() {
        CACHE = cache;
    }
    /**
     * 删除1个或多个键
     *
     * @author fzr
     * @param key 键(一个或多个)
     */
    public static void del(String... key) {
        if (key.length == 1) {
            key[0] = redisPrefix + key[0];
            CACHE.invalidate(key[0]);
        } else {
            for (int i=0; key.length > i; i++) {
                key[i] = redisPrefix + key[i];
            }
            CACHE.invalidateAll(Lists.newArrayList(key));
        }
    }

    /**
     * 获取key的值
     *
     * @author fzr
     * @param key 键
     * @return Object
     */
    public static Object get(String key) {
        key = redisPrefix + key;
        return CACHE.getIfPresent(key);
    }

    /**
     * 设置键值对
     *
     * @author fzr
     * @param key 键
     * @param value 值
     */
    public static void set(String key, Object value) {
        key = redisPrefix + key;
        CACHE.put(key, value);
    }

    /**
     * 设置键值对并设置时间
     *
     * @author fzr
     * @param key 键
     * @param value 值
     * @param time time要大于0 如果time小于等于0 将设置无限期
     */
    public static void set(String key, Object value, long time) {
        key = redisPrefix + key;
        if (time > 0) {
            // TODO 后续处理
            CACHE.put(key, value);
            // redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
        } else {
            set(key, value);
        }
    }

    /**
     * 获取key中field域的值
     *
     * @author fzr
     * @param key 键 不能为null
     * @param field 项 不能为null
     * @return 值
     */
    public static Object hGet(String key, String field) {
        key = redisPrefix + key;
        Object o = CACHE.get(key, k -> new HashMap<>());
        if (o instanceof Map) {
            return ((HashMap<?, ?>) o).get(field);
        }
        return null;
    }

    /**
     * 判断key中有没有field域名
     *
     * @author fzr
     * @param key 键
     * @param field 字段
     * @return Boolean
     */
    public static Boolean hExists(String key, Object field) {
        key = redisPrefix + key;
        Object ifPresent = CACHE.getIfPresent(key);
        if (ifPresent instanceof Map) {
            return ((HashMap<?, ?>) ifPresent).containsKey(field);
        }
        return Boolean.FALSE;
    }

    /**
     * 设置field1->N个域,对应的值是value1->N
     *
     * @author fzr
     * @param key 键
     * @param map 对应多个键值
     */
    @SuppressWarnings("unchecked")
    public static void hmSet(String key, Map<String, Object> map) {
        key = redisPrefix + key;
        Object o = CACHE.get(key, k -> new HashMap<>());
        if (o instanceof Map) {
            ((Map<String, Object>) o).putAll(map);
        }
    }

    /**
     * 向一张hash表中放入数据,如果不存在将创建
     *
     * @author fzr
     * @param key 键
     * @param item 项
     * @param value 值
     */
    @SuppressWarnings("unchecked")
    public static void hSet(String key, String item, Object value) {
        key = redisPrefix + key;
        Object o = CACHE.get(key, k -> new HashMap<>());
        if (o instanceof Map) {
            ((Map<String, Object>) o).put(item, value);
        }
    }

}
